import * as L from 'leaflet'
import 'leaflet/dist/leaflet.css'
import '@geoman-io/leaflet-geoman-free'
import '@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css'
import 'leaflet.polyline.snakeanim'
import * as positionDiaLogInstance from '../../components/RW/positionDialog/index'
import { getToken } from '../auth'
import aes from '../aes'
import { bedpositionDialogInstance , setUserInfo,positionDialogInit} from '../../components/RW/bedDialog'
import { unref } from 'vue'
const windowInstance: any = window
const token: string = getToken()
const mapOptions: IMapOptions = {
	zoomControl: true, //禁用 + - 按钮
	doubleClickZoom: false, // 禁用双击放大
	attributionControl: false, // 显示右下角leaflet标识
	minZoom: -3,
	maxZoom: 5,
	center: [0, 0],
	zoom: 0,
	crs: L.CRS.Simple,
	zoomSnap: 0.1,
	zoomDelta: 0.3,
}
class Map implements IMap {
	leafletMap = null
	tags = {}
	mapObj = {} as IMapobj
	polygon = null
	selectedId = ''
	nowIndex = 0
	playIndex = 1
	filterCode = ''
	positionType = ''
	markerList = []
	polygonList = {}
	nowPlayPolygonList = []
	devicesCallback = null
	positionDiaLog = null
	isActive = false
	isPlay = true
	showPositionDiaLog = false
	featureGroup = null
	warningTag = {}
	constructor(el: string, options: Record<string, any> = {}) {
		this.init(el, options)
	}
	/**
	 * @param 初始化leaflet
	 * @returns leafletMap
 */
	init(el: string, options?: Record<string, any>): any {
		if (!el) return
		const _this = this
		this.leafletMap = L.map(el, {
			...mapOptions,
			...options,
		})
		this.positionType = options.type
		this.leafletMap.on('movestart', () => (_this.isActive = true))
		this.leafletMap.on('moveend', () => (_this.isActive = false))
		this.leafletMap.on('zoomstart', () => (_this.isActive = true))
		this.leafletMap.on('zoomend', () => (_this.isActive = false))
		return this.leafletMap
	}
	/**
 * @param 加载地图
 * @returns void
 */
	loadMap(obj: IMapobj) {
		const _this = this
		return new Promise((resolve, reject) => {
			_this.mapObj = obj

			var imgUrl = _this.mapObj.imageFullUrl

			// 切换地图的时候把之前的标签数组清空

			var imageObj = new Image()
			imageObj.src = imgUrl
			imageObj.onload = function () {
				//删除图层所有控件
				_this.leafletMap.eachLayer(function (layer) {
					_this.leafletMap.removeLayer(layer)
				})
				positionDiaLogInstance.positionDiaLogRemove()
				_this.tags = {}
				let w = imageObj.width,
					h = imageObj.height

				let bounds = [[0, 0], [h, w]]

				let imageOverlay = L.imageOverlay(imgUrl, bounds).addTo(_this.leafletMap)

				imageOverlay.on('load', function () {
					_this.leafletMap.fitBounds(bounds)
				})
				_this.mapObj.width = imageObj.width
				_this.mapObj.height = imageObj.height
				resolve({ mapObj: _this.mapObj, leafletMap: _this.leafletMap })
			}
			imageObj.onerror = (e) => {
				reject(e)
			}
		})
	}
	/**
	 * @param 定位方法
	 * @returns void
	 */
	position(data) {
		const _this = this
		const windowInstance: any = window
		if (_this.isActive) {
			return
		}

		let showWarnTag = (warningRes) => {
			if (_this.warningTag.leafletLayer) {
				_this.warningTag.leafletLayerNaNpxove()
			}
			// warningTag =allWarningTags.find(x => x.tagCode == warningRes.tagCode) || {};
			_this.warningTag = warningRes
			if (!_this.warningTag.deviceCode) {
				return
			}
			var myIcons = L.divIcon({
				iconSize: [30, 30],
				iconAnchor: [15, 15],
				className: `marker_icon ` + warningRes.deviceCode,
				html: `
			<div  class="animate-wave-content">
			<img class="member_icon" src="${windowInstance.config.base_url + warningRes.userTypeIconUrl}"/>
			<div class="animate-wave">
					<div class="w1"></div>
					<div class="w2"></div>
					<div class="w3"></div>
					<div class="w4"></div>
					<div class="w5"></div>
					<div class="w6"></div>
			</div></div>`,
			})
			warningRes.isActive = true
			_this.warningTag.leafletTag.setIcon(myIcons)
		}
		for (let i = 0; i < data.length; i++) {
			let obj = data[i]
			obj.deviceCode = obj.deviceCode || obj.memberCode
			if (_this.mapObj.code != obj.mapCode) {
				continue
			}
			let myIcon = L.icon({
				iconUrl: windowInstance.config.base_url + obj.userTypeIconUrl,
				iconSize: [30, 30],
				iconAnchor: [15, 15],
				className: `marker_icon ` + obj.deviceCode,
			})
			// 雷达图标
			let envirIcon = L.divIcon({  html: `<div class='leaflet_bed_text'><p class="${obj.isWarning ? 'error ld' : 'ld'}">${obj.status || ''}</p> </div>`,
			iconAnchor: [-15, 12], })
			// 先去marker列表里看看能不能找到相同的，如果找到相同的就更新位置 否则就新增
			let r = _this.tags[obj.deviceCode]
			if (r) {
				// 找到了 就更新位置
				_this.tags[obj.deviceCode].leafletTag.setLatLng([obj.posY, obj.posX])
				if (obj.isWarning && !_this.tags[obj.deviceCode].isActive) {
					showWarnTag(_this.tags[obj.deviceCode])
				} else if (!obj.isWarning && _this.tags[obj.deviceCode].isActive) {
					_this.tags[obj.deviceCode].leafletTag.setIcon(myIcon)
					_this.tags[obj.deviceCode].isActive = false
				}
				_this.tags[obj.deviceCode].bedMarker && _this.tags[obj.deviceCode].bedMarker.setUserInfo(obj)
				_this.tags[obj.deviceCode].envirMarker && _this.tags[obj.deviceCode].envirMarker.setIcon(envirIcon)
			} else {
				// 没找到 创建
				let leafletTag = L.marker([obj.posY, obj.posX], {
					className: obj.deviceCode,
					radius: 10,
					fillColor: 'red',
					fillOpacity: 1,
					weight: 1,
					icon: myIcon,
					options: obj
				}).addTo(_this.leafletMap)
				let toolTipContent = `${obj.expandAttr?.bedName || obj.memberCode || '-'}`;
				let t = document.createElement("div");
				t.innerHTML = toolTipContent;
				leafletTag.setTooltipContent(t)
				leafletTag.bindTooltip(t, { permanent: true, offset: L.point(0, -10), direction: "top", className: "tag_info_tooltip" }).openTooltip();
				if (this.positionType === 'monitor' && obj.binderCategory === 'InPatient') {
					leafletTag.addEventListener('click', e => {
						this.addToopDiaLog(e)
					})
				}
				obj.leafletTag = leafletTag
				_this.reflushDevices()

				// 创建床垫状态显示信息
				if (obj.binderCategory === 'Bed') {
					let instance = positionDialogInit({})
					let bedIcon = L.divIcon({
						html: instance.$el,
						iconAnchor: [40, 70],
					})
					obj.bedMarker = L.marker([obj.posY, obj.posX], { icon: bedIcon }).addTo(this.leafletMap)
					obj.bedMarker.setUserInfo = setUserInfo(instance)
					obj.bedMarker.setUserInfo(obj)
					obj.leafletTag.closeTooltip()
				}


				// 创建雷达状态显示信息

				if (obj.binderCategory === 'Envir') {
					obj.envirMarker = L.marker([obj.posY, obj.posX], { icon: envirIcon }).addTo(this.leafletMap)
					obj.leafletTag.closeTooltip()
				}
				_this.tags[obj.deviceCode] = obj

			}
			_this.filterItem(obj)
		}
	}
	addToopDiaLog(e) {
		let options = e.target.options.options
		this.positionDiaLog = L.popup({
			className: "position_dialog"
		})
		if (!this.showPositionDiaLog) {
			this.positionDiaLog.setContent(positionDiaLogInstance.positionDialogInstance.$el)
		}
		this.positionDiaLog.setLatLng(e.latlng)
		console.log(this.mapObj,'mapObj')
		positionDiaLogInstance.setBedList({ mapId: this.mapObj.id , category:'InPatient,Asset' })
		positionDiaLogInstance.setUserInfo({ bedId: options.expandAttr.bedId, binderName: options.memberName , mapIds: options.memberId}, this.positionDeivce.bind(this))
		this.positionDiaLog.openOn(this.leafletMap)
		this.positionDiaLog.addEventListener('remove', () => {
			positionDiaLogInstance.closePositionDialog()
		})
	}
	positionDeivce(options) {
		let arr = this.getPositionTags()
		options = unref(options)
		let r = arr.find(item => {
			return item.expandAttr.bedId == options.bedId
		})
		if (!r) return;
		let device = this.tags[r.deviceCode]
		if (device) {
			positionDiaLogInstance.setUserInfo( null, this.positionDeivce.bind(this))
			this.positionDiaLog.setLatLng(device.leafletTag.getLatLng())
		}
	}
	getPositionTags() {
		let arr = []
		for (let key in this.tags) {
			arr.push(this.tags[key])
		}
		return arr
	}
	/**
	 *
	 * @param points 历史轨迹点
	 * @returns voids
	 * @description 绘画历史轨迹
	 */
	setHistoryLine(data) {
		if (!data.length) return

		const _this = this
		let nowPlayIndex = 0
		let polyline = null
		// 根据地图id分割成二维数组
		const splitArraysByMapId = (datas) => {
			const resultArrays = []
			let currentArray = []
			for (let i = 0, length = datas.length; i < length; i++) {
				if (i === 0 || datas[i].mapFid !== datas[i - 1].mapFid) {
					if (currentArray.length > 0) {
						resultArrays.push(currentArray)
					}
					currentArray = []
				}
				currentArray.push(datas[i])
			}

			if (currentArray.length > 0) {
				resultArrays.push(currentArray)
			}

			return resultArrays
		}

		const resultArrays = splitArraysByMapId(data)
		// 加载下一张地图的轨迹
		let loadNextMap = () => {
			if (nowPlayIndex < resultArrays.length - 1) {
				nowPlayIndex++
				showMarkerLine(resultArrays[nowPlayIndex])
			}
		}
		// 播放轨迹
		let showMarkerLine = async (datas: ITag[]) => {
			let firstObj = datas[0]
			await this.loadMapFunc(firstObj)
			const points = datas.map((item: ITag) => {
				return [item.posY || 0, item.posX || 0]
			})

			if (points.length == 1) {
				try {
					L.circleMarker(points[0], {
						radius: 5,
						fillColor: 'red',
						fillOpacity: 1,
						weight: 1,
					}).addTo(_this.leafletMap)
					setTimeout(() => {
						loadNextMap()
					}, 2000)
				} catch {
					loadNextMap()
				}
				return
			}

			polyline = L.polyline(points, { color: 'red', opacity: .6 }).addTo(_this.leafletMap)

			polyline.on('snakeend', (e) => {
				loadNextMap()
			})
			try {
				polyline.snakeIn()
			} catch {
				loadNextMap()
			}
		}

		// 默认执行一次
		showMarkerLine(resultArrays[nowPlayIndex])
	}
	/**
	 *
	 * @param points 区域轨迹点
	 * @returns voids
	 * @description 加载区域
	 */
	loadArea(points: []) {
		const _this = this
		setTimeout(() => {
			var bounds = points.map((item) => {
				return [item[0], item[1]]
			})
			let polygon = L.polygon(bounds, { color: 'red', zIndex: 999 }).addTo(_this.leafletMap)
		}, 500)
	}
	/**
	* @param 设置选中标签
		* @returns void	
 */
	setselectedId(id) {
		this.selectedId = id
	}
	/**
		* @param 设置刷新标签
		* @returns void
	*/
	reflushDevices() { }
	/**
		* @param 过滤标签
		* @returns void
	*/
	filterItem(obj: ITag) { }
	/**
		* @param 加载地图
		* @returns void
	*/
	async loadMapFunc(obj) {
		await this.loadMap({
			imageFullUrl: `${windowInstance.config.base_url}Maps/pic/${obj.mapId}?access_token=${token}`,
			width: 50,
			height: 50,
			code: obj.mapCode,
		})
	}
	/**
		* @param 重置
		* @returns void
	*/
	close() {
		positionDiaLogInstance.positionDiaLogRemove()
	}
}

export default Map
